package com.parse.tree;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import org.antlr.runtime.ANTLRFileStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.CommonTreeNodeStream;
import org.antlr.runtime.tree.Tree;

public class JavaTreeWalker {
	
	private static Set<org.antlr.runtime.tree.Tree> variableDeclartorNodes = new HashSet<org.antlr.runtime.tree.Tree>();
	private static Set<org.antlr.runtime.tree.Tree> typeNodes = new HashSet<org.antlr.runtime.tree.Tree>();
	private static Set<String> variableList = new HashSet<String>();
	private static Set<String> keywordList = new HashSet<String>();
	private static final String[] javaKeywords = { "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", "enum", "extends", "false", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "void", "volatile", "while" };
	private static final Set<String> javaKeywordSet = new HashSet<String>(Arrays.asList(javaKeywords));
	public static void main(String[] args) throws Exception {

		//Need absolute path
		ANTLRFileStream input = new ANTLRFileStream(
				"/Users/macpro/Documents/UCL/Tools and env/coursework/AntlrJavaParser/src/main/java/com/parse/tree/Class1.java");

		JavaLexer lexer = new JavaLexer(input);

		CommonTokenStream tokens = new CommonTokenStream(lexer);

		JavaParser parser = new JavaParser(tokens);

		JavaParser.javaSource_return r = parser.javaSource();

		CommonTree t = (CommonTree) r.getTree();

		//System.out.println(t.toStringTree());

		CommonTreeNodeStream nodes = new CommonTreeNodeStream(t);

		nodes.setTokenStream(tokens);

		JavaTreeParser walker = new JavaTreeParser(nodes);

		//System.out.println("\nWalk tree:\n");

		walker.javaSource();

		//System.out.println(tokens.toString());
		
		//System.out.println("\n\n\n");
		 printTree(t, 1);
		// System.out.println("\n\n\nvariable nodes: "+ variableDeclartorNodes);
		 
		for(Tree variableTree : variableDeclartorNodes){
			Tree variable = variableTree.getChild(0);
			variableList.add(variable.toString());
			//printTree(variableTree, 1);
		}
		
		System.out.println("\n\n\nVariables:" + variableList);
		
		System.out.println("\n\n\n Keywords:" + keywordList);
		
		System.out.println("\n\n\nTYPE LIST");
		
	    
		
		System.out.println(typeNodes);
		
		 

	}
	
	   public static void printTree(Tree t, int indent) {
	        System.out.println(t.toString());
	        printTreeHelper(t, indent);
	    }

	    private static void printTreeHelper(Tree t, int indent) {
	    	
	        if (t != null) {
	            StringBuffer sb = new StringBuffer(indent);
	            for (int i = 0; i < indent; i++)
	                sb = sb.append("   ");
	            for (int i = 0; i < t.getChildCount(); i++) {
	            	int type = t.getChild(i).getType();
	            	if(type == 174){
	            		variableDeclartorNodes.add(t.getChild(i));
	            	}
	            	if(type == 169){
	            		Tree typeNode = t.getChild(i);
	            		while(typeNode.getChildCount() >0)
	            			typeNode = typeNode.getChild(0);
	            		//System.out.println("Type Child: "+ typeNode.toString());
	            		typeNodes.add(typeNode);
	            	}
	            	String nodeValue = t.getChild(i).toString();
					if(javaKeywordSet.contains(nodeValue))
	            		keywordList.add(nodeValue);
	            		
	                //if (t.getChild(i).getType()==4)
	                System.out.println(sb.toString() + t.getChild(i).toString()
	                + " [" + JavaParser.tokenNames[type]
	                + "]");
	                printTreeHelper((CommonTree) t.getChild(i), indent + 1);
	            }
	        }
	       
	    }
}
